#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <wiiuse/wpad.h>
#include <ogc/conf.h>
#include <ogc/pad.h>
#include <ogc/isfs.h>
#include <CheckRegion.h>
#include <fat.h>

#include "network.h"
#include "tools.h"
#include "filelog.h"


bool NetworkInitialized = false;

extern s32 __CONF_GetTxt(const char *name, char *buf, int length);
extern s32 CONF_Get(const char *name, void *buffer, u32 length);
extern void __exception_setreload(int t);

static void *xfb = NULL;
static GXRModeObj *rmode = NULL;

//---------------------------------------------------------------------------------
void Initialize(void) {
//---------------------------------------------------------------------------------
	__exception_setreload(0); // In the event of a code dump, app will exit right away
	VIDEO_Init();
	WPAD_Init();
	PAD_Init();
	CONF_Init();
	ISFS_Initialize();
	fatInitDefault();
	rmode = VIDEO_GetPreferredMode(NULL);
	xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
	console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
	VIDEO_Configure(rmode);
	VIDEO_SetNextFramebuffer(xfb);
	VIDEO_SetBlack(FALSE);
	VIDEO_Flush();
	VIDEO_WaitVSync();
	if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
	
	NetworkInitialized = NetworkInit();
	Log_Init("InspectMii.log", true);
	return;
}

//---------------------------------------------------------------------------------
void Deinitialize(void) {
//---------------------------------------------------------------------------------
	NetworkDeinit();
	Log_Deinit();
	return;
}

//---------------------------------------------------------------------------------
void pressanykey(void) {
//---------------------------------------------------------------------------------
	#ifdef DOLPHIN
	sleep(100); // Set delay for recording
	return;
	#endif
	do
	{
		WPAD_ScanPads();
		PAD_ScanPads();
		VIDEO_WaitVSync();
	} while(!(WPAD_ButtonsDown(0) || PAD_ButtonsDown(0)));
	return;
}

//---------------------------------------------------------------------------------
void PrintText(const char *name) {
//---------------------------------------------------------------------------------
	CHANGE_COLOR(CYAN);
	printf("%s=", name);
	char buf[20]; //Extra long
	if (__CONF_GetTxt(name, buf, 20) < 0) {
		CHANGE_COLOR(RED);
		strcpy(buf, "?");
	} else {
		CHANGE_COLOR(WHITE);
	}
	printf("%s\n", buf);
	Log("%s=%s\r\n", name, buf);
	return;
}

//---------------------------------------------------------------------------------
void PrintValue1(const char *text, const char **options, s32 val) {
//---------------------------------------------------------------------------------
	CHANGE_COLOR(CYAN);
	printf("%s", text);
	Log("%s", text);
	if (val < 0) {
		PRINT_HEX_ERROR(RED, val);
		LOG_HEX_ERROR(val);
	} else {
		CHANGE_COLOR(WHITE);
		if (options == NULL)
		{
			printf("%i\n", val);
			Log("%i\r\n", val);
		} else {
			printf("%i [%s]\n", val, options[val]);
			Log("%i [%s]\r\n", val, options[val]);
		}
	}
	return;
}

//---------------------------------------------------------------------------------
void PrintValue2(const char *text, s8 * hexval, u8 length) {
//---------------------------------------------------------------------------------
	int i;
	bool empty = true;

	for(i=0; i<length; i++) {
		if (hexval[i] != 0) {
			empty = false;
			break;
		}
	}
	
	CHANGE_COLOR(CYAN);
	printf("%s", text);
	Log("%s", text);
	
	if (empty) {
		CHANGE_COLOR(RED);
		printf("[No Entry]\n\n");
		Log("[No Entry]\r\n\r\n");
	} else {
		CHANGE_COLOR(WHITE);
		printf("{");
		Log("{");
		for(i=0; i < length; i++) {
			printf("%02x%c", (u32) hexval[i], (i == length-1) ? '}' : ',');
			Log("%02x%c", (u32) hexval[i], (i == length-1) ? '}' : ',');
		}
		printf(" [");
		Log(" [");
		for(i=0; i < length-1; i++) {
			if(hexval[i] != 0) {
				printf("%c", hexval[i]);
				Log("%c", hexval[i]);
			}
		}
		printf("]\n\n");
		Log("]\r\n");
	}
	return;
}

//---------------------------------------------------------------------------------
void Banner(const char *title) {
//---------------------------------------------------------------------------------
	CLEAR_SCREEN();
	CHANGE_COLOR(GREEN);
	printf("\n\n********************************************************************************");
	printf ("\x1b[3;%iH%s\n", 40-strlen(title)/2, title);
	printf("********************************************************************************");
	Log("\r\n\r\n********************************************************************************\r\n");
	Log("%s\r\n", title);
	Log("********************************************************************************\r\n");
	CHANGE_COLOR(WHITE);
	return;
}
